"""日志控件"""

import collections
import logging
import qte.signal
from PyQt5 import QtCore, QtGui, QtWidgets

_ERROR_HAPPENED = qte.signal.Signal()

class LoggingModel(QtCore.QAbstractItemModel, logging.Handler):

    def __init__(self):
        super().__init__()
        self.buffer = collections.deque(maxlen=1000)
        self.cache = []
        self.formatter = logging.Formatter(
            "%(asctime)s [%(processName)s] %(message)s",
            "%Y-%m-%d %H:%M:%S"
        )
        standardIcon = QtWidgets.QApplication.style().standardIcon
        self.icons = {
            logging.DEBUG: standardIcon(QtWidgets.QStyle.SP_FileDialogDetailedView),
            logging.INFO: standardIcon(QtWidgets.QStyle.SP_MessageBoxInformation),
            logging.WARNING: standardIcon(QtWidgets.QStyle.SP_MessageBoxWarning),
            logging.ERROR: standardIcon(QtWidgets.QStyle.SP_MessageBoxCritical),
        }
        self.colors = {
            logging.DEBUG: QtGui.QColor(QtCore.Qt.darkGray),
            logging.INFO: QtGui.QColor(QtCore.Qt.black),
            logging.WARNING: QtGui.QColor(QtCore.Qt.darkYellow),
            logging.ERROR: QtGui.QColor(QtCore.Qt.red),
        }
        logging.getLogger().addHandler(self)

    def set_max_size(self, max_size):
        self.buffer = collections.deque(self.buffer, max_size)

    def emit(self, record):
        global _ERROR_HAPPENED
        if not self.cache:
            QtCore.QTimer.singleShot(50, self._delay_insert)
        self.cache.append({
            QtCore.Qt.DecorationRole: self.icons.get(record.levelno),
            QtCore.Qt.TextColorRole: self.colors.get(record.levelno),
            QtCore.Qt.DisplayRole: self.formatter.format(record)
        })

        # 如果发生错误的log 发起一个错误信号
        if record.levelno == 40:
            _ERROR_HAPPENED.emit()

    def _delay_insert(self):
        self.beginResetModel()
        self.buffer.extend(self.cache)
        self.endResetModel()
        del self.cache[:]

    def columnCount(self, _index):
        return 1

    def rowCount(self, index):
        if index.isValid():
            return 0
        return len(self.buffer)

    def index(self, row, column, _parent):
        return self.createIndex(row, column)

    def parent(self, _index):
        return QtCore.QModelIndex()

    def data(self, index, role):
        return self.buffer[index.row()].get(role)


class LoggingView(QtWidgets.QTreeView):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setHeaderHidden(True)
        self.setRootIsDecorated(False)
        self.setVerticalScrollMode(self.ScrollPerPixel)
        self.setSelectionMode(self.NoSelection)
        self.setAlternatingRowColors(True)
        self.setTextElideMode(QtCore.Qt.ElideNone)
        self.setWordWrap(True)
        self.setModel(LoggingModel())
        self.model().modelReset.connect(self.scrollToBottom)
